最近公司專案有用到「Airflow」來去做排程的處理,剛好跟我們今天要介紹的模式一樣,當我們有一個需求是希望一個工作結束後,會去呼叫另一個工作去執行,像這樣一個呼叫一個,這時候就很適合用 Chain of Responsibility 模式,話不囉嗦,我們直接來看範例!
避免請求發送者與接收者耦合在一起,讓多個對象都有可能接收請求,將這些對象連接成一條鏈,並且沿著這條鏈傳遞請求,直到有對象處理它為止。
(圖片來源:https://media.geeksforgeeks.org/wp-content/uploads/desigmpatternuml1.png)
TaskHandler
是一個抽象類別,當建構時會傳入下一個需要被呼叫的 Task,HandleTask()
是屆時繼承自TaskHandler
的實體需要去覆寫的方法,而ExecuteTask()
則是去啟動工作,裡面會先去執行實體覆寫的HandleTask()
,再去判斷說如果在建構時有傳入下一個需要被呼叫的 Task,那就再去執行他的ExecuteTask()
,否則會跳出,結束整個工作。using System;
namespace DAY27_Chain_of_Responsibility
{
internal class Program
{
static void Main(string[] args)
{
// 建構子中會帶入下個要執行的Task
TaskHandler task3 = new Task3(null);
TaskHandler task2 = new Task2(task3);
TaskHandler task1 = new Task1(task2);
task1.ExecuteTask();
}
}
public abstract class TaskHandler
{
protected TaskHandler _nextHandler;
// 建構子帶入下個要做的Task
public TaskHandler(TaskHandler nextHandler)
{
_nextHandler = nextHandler;
}
public void ExecuteTask()
{
// 先執行各別Task覆寫的HandleTask()
HandleTask();
// 如果有下個Task要做則執行下個Task的ExecuteTask()
if (_nextHandler != null)
{
Console.WriteLine($"{this.GetType().Name}完成,將接著執行{_nextHandler.GetType().Name}");
_nextHandler.ExecuteTask();
}
else
{
Console.WriteLine("工作結束!");
}
}
public abstract void HandleTask();
}
public class Task1 : TaskHandler
{
public Task1(TaskHandler handler) : base(handler){}
public override void HandleTask()
{
Console.WriteLine($"Task1處理完畢!");
}
}
public class Task2 : TaskHandler
{
public Task2(TaskHandler handler) : base(handler) { }
public override void HandleTask()
{
Console.WriteLine($"Task2處理完畢!");
}
}
public class Task3 : TaskHandler
{
public Task3(TaskHandler handler) : base(handler) { }
public override void HandleTask()
{
Console.WriteLine($"Task3處理完畢!");
}
}
}
今天我們透過 Chain of Responsibility 模式,簡單的說明如何去執行一個排程工作,當一個工作結束後,會再去負責呼叫下一個工作起來運作直到結束,如果大家對於排程這塊有興趣的話,可以去玩玩看 Apache 的「Ariflow」或者是 DotNet 的「Hangfire」,都是不錯的排程工具,那我們就明天繼續囉!